package com.tang.sharding.algorithm.standard;

import com.tang.sharding.algorithm.AbstractDateShardingAlgorithm;
import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.RangeShardingValue;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Set;
import java.util.StringJoiner;

/**
 * @author Tang
 * @classname WeekShardingAlgorithm
 * @description [  ]
 * @date 2021/8/9 10:26
 */
public class WeekShardingAlgorithm extends AbstractDateShardingAlgorithm {

    @Override
    public String doPreciseSharding(PreciseShardingValue<Date> shardingValue) {
        LocalDate localDate = LocalDate.from(shardingValue.getValue().toInstant().atZone(ZoneId.systemDefault()));
        StringJoiner joiner = new StringJoiner("_");
        joiner.add(shardingValue.getLogicTableName());
        int weekValue = localDate.getDayOfWeek().getValue();
        localDate = localDate.plusDays(-weekValue + 1);
        joiner.add((String.valueOf(localDate.getYear())));
        joiner.add((String.valueOf(localDate.getMonthValue())));
        joiner.add(String.valueOf(localDate.getDayOfMonth()));
        return joiner.toString();
    }

    @Override
    protected void doDateRangeSharding(Set<String> tableNamesSet, RangeShardingValue<Date> shardingValue,
                                       LocalDateTime t1, LocalDateTime t2) {
        t1 = t1.withHour(0).withMinute(0).withSecond(0);
        t1 = t1.plusDays(-t1.getDayOfWeek().getValue() + 1);
        t2 = t2.withHour(0).withMinute(0).withSecond(0);
        while (t1.isBefore(t2) || (t1.compareTo(t2) == 0)) {
            StringJoiner weekStringJoiner = new StringJoiner("_");
            weekStringJoiner.add(shardingValue.getLogicTableName())
                    .add((String.valueOf(t1.getYear())))
                    .add((String.valueOf(t1.getMonthValue())))
                    .add((String.valueOf(t1.getDayOfMonth())));
            tableNamesSet.add(weekStringJoiner.toString());
            t1 = t1.plusWeeks(1);
        }
    }
}